import React from 'react'
import SearchHeader from 'common/SearchHeader'
import { Flex, Toast } from 'antd-mobile'
import styles from './index.module.scss'
import Filter from './Filter'
import { getCurrentCity } from 'utils/city'
import http from 'utils/http'
import HouseItem from 'common/HouseItem'
import Sticky from 'common/Sticky'
import NoHouse from 'common/NoHouse'

import {
  AutoSizer,
  List,
  WindowScroller,
  InfiniteLoader,
} from 'react-virtualized'

class House extends React.Component {
  state = {
    city: {
      label: '北京',
      value: '',
    },
    // 这个就是请求时, 需要加上的过滤条件
    filters: {},
    // 存储的是展示的房屋列表
    list: [],
    // 存储的是房屋的总数
    count: -1,
    isLoading: false,
  }
  async componentDidMount() {
    // 先获取城市信息
    const city = await getCurrentCity()
    this.setState(
      {
        city,
      },
      () => {
        // 根据城市信息, 再加载对应的房源
        this.getHouseList()
      }
    )
  }

  filterChange(selectedValues) {
    // 每次修改条件, 应该重新从顶部展示
    window.scrollTo(0, 0)
    const paramsObj = this.parseFilter(selectedValues)
    this.setState(
      {
        filters: paramsObj,
        list: [],
      },
      () => {
        // 确认时, 过滤条件存好了, 再发请求
        this.getHouseList()
      }
    )
  }

  async getHouseList(start = 1, end = 30) {
    Toast.loading('拼命加载中...', 0)
    const res = await http.get('/houses', {
      params: {
        cityId: this.state.city.value,
        ...this.state.filters,
        start: start,
        end: end,
      },
    })
    const { list, count } = res.data.body
    this.setState({
      list: [...this.state.list, ...list],
      count,
    })
    Toast.hide()
    if (start === 1) {
      // 应该给用户一个提示, 告诉总计多少条数据
      Toast.info(`总计 ${this.state.count} 套房源数据`, 2, null, false)
    }
  }

  parseFilter(selectedValues) {
    // 实际, 我们拿到的selectedValues, 和后台需要的请求参数, 还不太一致
    // 需要进行参数的处理的
    const params = {}
    params.rentType = selectedValues.mode[0]
    params.price = selectedValues.price[0]
    params.more = selectedValues.more.join(',')

    // 如果数组的长度是3, 且第三项有值(值还要是非null), 说明: 用户选择了更精确的地址, 那么就用第三项的值
    // 否则: 就取第二项的值
    const arr = selectedValues.area
    const key = arr[0] // 可能是area, 也可能是subway
    if (arr.length === 3 && arr[2] !== 'null') {
      // 说明, 有更精确的地址, 以更精确的地址为准
      params[key] = arr[2]
    } else {
      params[key] = arr[1]
    }
    return params
  }

  // 渲染每一行的结构的, 可视区渲染的原理, 渲染的那几个盒子都是定位的
  // 所有的位置, 都是根据第几个盒子, 行高, 动态计算的
  rowRenderer({ key, index, style }) {
    // 如果滑动的比较多了, index就会超出list有的数据的范围
    // item 就变成 undefined
    const item = this.state.list[index]
    if (item) {
      return <HouseItem item={item} key={key} style={style}></HouseItem>
    } else {
      // 如果没有取到, 说明数据还没加载回来, 不应该报错, 应该给个假的盒子占位置
      return (
        <div key={key} style={style}>
          正在加载... 请稍后...
        </div>
      )
    }
  }

  // onRowsRendered({ overscanStopIndex }) {
  //   // 最后一个看不见的盒子的下标
  //   // 如果看不见的盒子的下标, 到达了最后一个盒子的下标, 就应该加载更多了
  //   if (overscanStopIndex >= this.state.list.length - 1) {
  //     if (this.state.isLoading) return
  //     this.setState(
  //       {
  //         isLoading: true,
  //       },
  //       () => {
  //         // 不在加载中, 才加载更多
  //         console.log('加载更多... 发送ajax请求... ')
  //       }
  //     )
  //   }
  // }

  // 判断当前 index 的项, 是否有值
  isRowLoaded({ index }) {
    return !!this.state.list[index]
  }

  // 如果发现当前项没有值, 会触发loadMoreRows, 就要加载更多了
  // 这边需要将getHouseList return, 因为是一个async函数, 直接接收, 会得到一个promise对象
  // 在插件内部, 会await这个promise对象, 成功了, 说明数据回来了, 用以通知视图的更新
  // await this.getHouseList(startIndex + 1, stopIndex + 1)
  // console.log(123)
  loadMoreRows({ startIndex, stopIndex }) {
    return this.getHouseList(startIndex + 1, stopIndex + 1)
  }

  renderList() {
    const { count } = this.state
    if (count > 0) {
      return (
        <InfiniteLoader
          rowCount={count}
          isRowLoaded={this.isRowLoaded.bind(this)}
          loadMoreRows={this.loadMoreRows.bind(this)}
          minimumBatchSize={30}
        >
          {({ onRowsRendered, registerChild }) => (
            <WindowScroller>
              {({ height, scrollTop }) => (
                <AutoSizer>
                  {({ width }) => (
                    <List
                      ref={registerChild}
                      autoHeight
                      scrollTop={scrollTop}
                      height={height}
                      width={width}
                      rowCount={count}
                      rowHeight={120}
                      rowRenderer={this.rowRenderer.bind(this)}
                      onRowsRendered={onRowsRendered}
                    ></List>
                  )}
                </AutoSizer>
              )}
            </WindowScroller>
          )}
        </InfiniteLoader>
      )
    } else if (count === 0) {
      return <NoHouse></NoHouse>
    } else {
      // 如果 count < 0, 说明此时请求还没有回来
      return null
    }
  }

  render() {
    return (
      <div className={styles.house}>
        {/* 房屋列表的头部 */}
        <Flex className="house-title">
          <span className="iconfont icon-back"></span>
          {/* 自己封装的组件上, 添加了 className的prop, 不做处理, 类名会丢失 */}
          <SearchHeader
            className="search"
            cityName={this.state.city.label}
          ></SearchHeader>
        </Flex>

        {/* 展示的过滤组件 */}
        <Sticky>
          <Filter filterChange={this.filterChange.bind(this)}></Filter>
        </Sticky>

        {/* 这里要展示列表 */}
        {/* 
          WindowScroller的使用
            height: 设置 list 的高度
            autoHeight 让list父元素的高度自适应, 被list撑开
            scrollTop 距离顶部的高度
          InfiniteLoader的使用
            rowCount: 总条数
            isRowLoaded: 用于判断当前的行是否存在
            minimumBatchSize: 一次加载的最小条数
        */}
        <div className="house-list">{this.renderList()}</div>
      </div>
    )
  }
}

export default House
